package com.ib.algokit.forex;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import com.ib.algokit.history.ProfitLimitClosedEvent;
import com.ib.algokit.history.StopLossClosedEvent;
/**
 * Holds pair states at certain point in time.<br/>
 * Holds the following associated variables:
 * <ul>
 * <li>changeDetailsRanges(Set&lt;ChangeDetailsRange&gt;)</li>
 * </ul>
 * @author dmisev
 */
public class ForexPairStateRanges implements Serializable{
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
     * private final Set&lt;ChangeDetails&gt; changeDetailsRanges;
     */
    private final Set<ChangeDetailsRange> changeDetailsRanges;
    
    private HashSet<ProfitLimitClosedEvent> longProfitOutcomes;
    
    private HashSet<ProfitLimitClosedEvent> shortProfitOutcomes;
    
    private HashSet<StopLossClosedEvent> longLossOutcomes;
    
    private HashSet<StopLossClosedEvent> shortLossOutcomes;
    
    public HashSet<ProfitLimitClosedEvent> getLongProfitOutcomes(){
    	return longProfitOutcomes;
    }
    
    public HashSet<ProfitLimitClosedEvent> getShortProfitOutcomes(){
    	return shortProfitOutcomes;
    }
    
    public HashSet<StopLossClosedEvent> getLongLossOutcomes(){
    	return longLossOutcomes;
    }
    
    public HashSet<StopLossClosedEvent> getShortLossOutcomes(){
    	return shortLossOutcomes;
    }
    
//    public HashSet<ProfitLimitClosedEvent> getPairLongProfitOutcomes(){
//    	return longProfitOutcomes;
//    }
//
//    public HashSet<ProfitLimitClosedEvent> getPairShortProfitOutcomes(){
//        return shortProfitOutcomes;
//    }
//
//    public HashSet<StopLossClosedEvent> getPairLongLossOutcomes(){
//    	return longLossOutcomes;
//    }
//
//    public HashSet<StopLossClosedEvent> getPairShortLossOutcomes(){
//    	return shortLossOutcomes;
//    }
    
    public void addLongProfitLimitClosedEvent(ProfitLimitClosedEvent event){
        if(longProfitOutcomes==null){
            longProfitOutcomes= new HashSet<ProfitLimitClosedEvent>();
        }
    	longProfitOutcomes.add(event);
    }
    
    public void addShortProfitLimitClosedEvent(ProfitLimitClosedEvent event){    	
    	if(shortProfitOutcomes==null){
    		shortProfitOutcomes= new HashSet<ProfitLimitClosedEvent>();
        }
    	shortProfitOutcomes.add(event);
    }
    
    public void addLongStopLossClosedEvent(StopLossClosedEvent event){
    	if(longLossOutcomes==null){
    		longLossOutcomes= new HashSet<StopLossClosedEvent>();
        }
    	longLossOutcomes.add(event);
    }
    
    public void addShortStopLossClosedEvent(StopLossClosedEvent event){   	
    	if(shortLossOutcomes==null){
    		shortLossOutcomes= new HashSet<StopLossClosedEvent>();
        }
    	shortLossOutcomes.add(event);
    }
    
    public ForexPairStateRanges(Set<ChangeDetailsRange> changeDetailsRanges){
        this.changeDetailsRanges=changeDetailsRanges;
    }
    /**
     * returns the associated changeDetailsRanges(Set&lt;ChangeDetailsRange&gt;)
     * @return
     */
    public Set<ChangeDetailsRange> getChangeDetailsRanges(){
        return this.changeDetailsRanges;
    }
    
//    public String getLevelOneHashKey(){
//    	StringBuffer up=new StringBuffer();
//    	StringBuffer nochange=new StringBuffer();
//    	StringBuffer down=new StringBuffer();
//    	for(ChangeDetailsRange cdr:changeDetailsRanges){
//    		String forexPair=cdr.getForexPair();
//    		double percChange=cdr.getPercChange();
//    		if(percChange<0){
//    			down.append(forexPair+"-");
//    		}else if(percChange>0){
//    			up.append(forexPair+"+");
//    		}else{
//    			nochange.append(forexPair+"=");
//    		}
//    	}
//    	StringBuffer out=new StringBuffer();
//    	out.append(up);
//    	out.append(nochange);
//    	out.append(down);
//    	return out.toString();
//    }
//
//    public double getLevelTwoHashKey(){
//    	double totalPercChange=0;
//    	for(ChangeDetailsRange cdr:changeDetailsRanges){
//    		double percChange=cdr.getPercChange();
//    		totalPercChange+=percChange;
//    	}
//    	return totalPercChange;
//    }
    
//    public double getUpHashKey(){
//    	double totalPercChange=0;
//    	for(ChangeDetailsRange cdr:changeDetailsRanges){
//    		double percChange=cdr.getPercChange();
//    		if(percChange>0){
//    			totalPercChange+=percChange;
//    		}
//    	}
//    	return totalPercChange;
//    }
//
//    public double getDownHashKey(){
//    	double totalPercChange=0;
//    	for(ChangeDetailsRange cdr:changeDetailsRanges){
//    		double percChange=cdr.getPercChange();
//    		if(percChange<0){
//    			totalPercChange+=percChange;
//    		}
//    	}
//    	return totalPercChange;
//    }
    
	public double getPairPercChange(String pair){
		for(ChangeDetailsRange cdr:changeDetailsRanges){			
			if(pair.equals(cdr.getForexPair())){
				double percChange=cdr.getPercChange();
				return percChange;
			}
		}
		throw new RuntimeException("shouldn't happen");
	}
	
	public boolean allPairsPercChangeMatchByOffset(double offset, Set<ChangeDetails> currentChangeDetailsRanges){
		for(ChangeDetails cdr:currentChangeDetailsRanges){
			String pair = cdr.getForexPair();
			double percChange=cdr.getPercChange();
			double memoryPercChange=getPairPercChange(pair);
			if(Math.abs(memoryPercChange-percChange)>offset ){
				return false;
			}
		}		
//		for(ChangeDetailsRange cdr:changeDetailsRanges){
//			String pair = cdr.getForexPair();
//    		double percChange=cdr.getPercChange();
//    		
//    	}
		return true;
	}
	
	public boolean allRelevantPairsPercChangeMatchByOffset(String symbol, String underlying, double offset, Set<ChangeDetails> currentChangeDetailsRanges){
		for(ChangeDetails cdr:currentChangeDetailsRanges){
			String pair = cdr.getForexPair();
			double percChange=cdr.getPercChange();
			double memoryPercChange=getPairPercChange(pair);
			if((pair.startsWith(symbol)||pair.startsWith(underlying)||pair.endsWith(symbol)||pair.endsWith(underlying)) && Math.abs(memoryPercChange-percChange)>offset ){
				return false;
			}
		}
		return true;
	}

	public boolean thisPairPercChangeMatchByOffset(String thisPair, double offset, Set<ChangeDetails> currentChangeDetailsRanges){
		for(ChangeDetails cdr:currentChangeDetailsRanges){
			String pair = cdr.getForexPair();
			double percChange=cdr.getPercChange();
			double memoryPercChange=getPairPercChange(pair);
			if(pair.equals(thisPair)){
				return (Math.abs(memoryPercChange-percChange)<=offset);
			}
		}
		return true;
	}
}
